Image Classification by Transfer Learning and Comparison of Custom CNN Model to Pre-trained Models.

Project by: Janvi Patel (0678100) and Prerak Trivedi (0678127)

This code requires python 3.8.6 64-bit version to install tensorflow and keras.

Checking for the libraries and installing them.

In [3]:
import sys
!{sys.executable} -m pip install tensorflow random2 numpy pandas matplotlib seaborn scikit-learn keras opencv-python tqdm Pillow dash flask plotly
Requirement already satisfied: tensorflow in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (2.3.1)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: pandas in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.1.4)
Requirement already satisfied: matplotlib in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (3.3.3)
Requirement already satisfied: seaborn in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (0.11.0)
Requirement already satisfied: scikit-learn in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (0.23.2)
Requirement already satisfied: keras in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (2.4.3)
Requirement already satisfied: opencv-python in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (4.4.0.46)
Requirement already satisfied: tqdm in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (4.54.0)
Requirement already satisfied: Pillow in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (8.0.1)
Requirement already satisfied: dash in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.0)
Requirement already satisfied: flask in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.1.2)
Requirement already satisfied: plotly in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (4.14.0)
Requirement already satisfied: flask-compress in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from dash) (1.8.0)
Requirement already satisfied: plotly in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (4.14.0)
Requirement already satisfied: dash-renderer==1.8.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from dash) (1.8.3)
Requirement already satisfied: dash-html-components==1.1.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from dash) (1.1.1)
Requirement already satisfied: dash-table==4.11.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from dash) (4.11.1)
Requirement already satisfied: dash-core-components==1.14.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from dash) (1.14.0)
Requirement already satisfied: flask in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.1.2)
Requirement already satisfied: future in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from dash) (0.18.2)
Requirement already satisfied: click>=5.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from flask) (7.1.2)
Requirement already satisfied: Jinja2>=2.10.1 in c:\users\janvi\appdata\roaming\python\python38\site-packages (from flask) (2.11.2)
Requirement already satisfied: Werkzeug>=0.15 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from flask) (1.0.1)
Requirement already satisfied: itsdangerous>=0.24 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from flask) (1.1.0)
Requirement already satisfied: h5py in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from keras) (2.10.0)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: pyyaml in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from keras) (5.3.1)
Requirement already satisfied: scipy>=0.14 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from keras) (1.5.4)
Requirement already satisfied: cycler>=0.10 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from matplotlib) (0.10.0)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from matplotlib) (2.4.7)
Requirement already satisfied: python-dateutil>=2.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from matplotlib) (2.8.1)
Requirement already satisfied: Pillow in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (8.0.1)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from matplotlib) (1.3.1)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: python-dateutil>=2.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from matplotlib) (2.8.1)
Requirement already satisfied: pytz>=2017.2 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from pandas) (2020.4)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
WARNING: You are using pip version 20.3.1; however, version 20.3.3 is available.
You should consider upgrading via the 'C:\Users\Janvi\AppData\Local\Programs\Python\Python38\python.exe -m pip install --upgrade pip' command.
Requirement already satisfied: retrying>=1.3.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.3.3)
Collecting random2
  Downloading random2-1.0.1.zip (21 kB)
Requirement already satisfied: joblib>=0.11 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from scikit-learn) (0.17.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from scikit-learn) (2.1.0)
Requirement already satisfied: scipy>=0.14 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from keras) (1.5.4)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: matplotlib in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (3.3.3)
Requirement already satisfied: pandas in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.1.4)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: scipy>=0.14 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from keras) (1.5.4)
Requirement already satisfied: termcolor>=1.1.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (1.1.0)
Requirement already satisfied: tensorflow-estimator<2.4.0,>=2.3.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (2.3.0)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: opt-einsum>=2.3.2 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (3.3.0)
Requirement already satisfied: keras-preprocessing<1.2,>=1.1.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (1.1.2)
Requirement already satisfied: astunparse==1.6.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (1.6.3)
Requirement already satisfied: wheel>=0.26 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.35.1)
Requirement already satisfied: protobuf>=3.9.2 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (3.14.0)
Requirement already satisfied: wrapt>=1.11.1 in c:\users\janvi\appdata\roaming\python\python38\site-packages (from tensorflow) (1.11.2)
Requirement already satisfied: google-pasta>=0.1.8 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.2.0)
Requirement already satisfied: absl-py>=0.7.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.11.0)
Requirement already satisfied: tensorboard<3,>=2.3.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (2.4.0)
Requirement already satisfied: h5py in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from keras) (2.10.0)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: gast==0.3.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.3.3)
Requirement already satisfied: grpcio>=1.8.6 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (1.33.2)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: wheel>=0.26 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.35.1)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: brotli in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from flask-compress->dash) (1.0.9)
Requirement already satisfied: flask in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.1.2)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: MarkupSafe>=0.23 in c:\users\janvi\appdata\roaming\python\python38\site-packages (from Jinja2>=2.10.1->flask) (1.1.1)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (1.7.0)
Requirement already satisfied: Werkzeug>=0.15 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from flask) (1.0.1)
Requirement already satisfied: wheel>=0.26 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.35.1)
Requirement already satisfied: markdown>=2.6.8 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (3.3.3)
Requirement already satisfied: protobuf>=3.9.2 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (3.14.0)
Requirement already satisfied: grpcio>=1.8.6 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (1.33.2)
Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (0.4.2)
Requirement already satisfied: numpy in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (1.18.5)
Requirement already satisfied: requests<3,>=2.21.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (2.25.0)
Requirement already satisfied: setuptools>=41.0.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (50.3.2)
Requirement already satisfied: google-auth<2,>=1.6.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (1.23.0)
Requirement already satisfied: absl-py>=0.7.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorflow) (0.11.0)
Requirement already satisfied: pyasn1-modules>=0.2.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow) (0.2.8)
Requirement already satisfied: six in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from plotly) (1.15.0)
Requirement already satisfied: cachetools<5.0,>=2.0.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow) (4.1.1)
Requirement already satisfied: rsa<5,>=3.1.4 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow) (4.6)
Requirement already satisfied: setuptools>=41.0.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (50.3.2)
Requirement already satisfied: requests-oauthlib>=0.7.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<3,>=2.3.0->tensorflow) (1.3.0)
Requirement already satisfied: google-auth<2,>=1.6.3 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (1.23.0)
Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from pyasn1-modules>=0.2.1->google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow) (0.4.8)
Requirement already satisfied: idna<3,>=2.5 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow) (2.10)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow) (1.26.2)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow) (2020.11.8)
Requirement already satisfied: chardet<4,>=3.0.2 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow) (3.0.4)
Requirement already satisfied: requests<3,>=2.21.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from tensorboard<3,>=2.3.0->tensorflow) (2.25.0)
Requirement already satisfied: oauthlib>=3.0.0 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<3,>=2.3.0->tensorflow) (3.1.0)
Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in c:\users\janvi\appdata\local\programs\python\python38\lib\site-packages (from pyasn1-modules>=0.2.1->google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow) (0.4.8)
Building wheels for collected packages: random2
  Building wheel for random2 (setup.py): started
  Building wheel for random2 (setup.py): finished with status 'done'
  Created wheel for random2: filename=random2-1.0.1-py3-none-any.whl size=12075 sha256=19734e248c798e826c441d7f96bcdb08709158ca55d4adffd4d412114c2bf6fb
  Stored in directory: c:\users\janvi\appdata\local\pip\cache\wheels\6e\ca\f2\082dec051ffcaec249ae491b8c90e305726a7390274682b4a4
Successfully built random2
Installing collected packages: random2
Successfully installed random2-1.0.1

Loading libraries for models and visualization

In [32]:
#    ML CLASSIFICATION MODEL  ***********************-------------------------------------------------------
import tensorflow as tf
import random as rn

# Data Visualisation 
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
import seaborn as sns

#model selection
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.metrics import accuracy_score,precision_score,recall_score,confusion_matrix,roc_curve,roc_auc_score
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import LabelEncoder
 
#configure
# sets matplotlib to inline and displays graphs below the corressponding cell.
#% matplotlib inline  
style.use('fivethirtyeight')
sns.set(style='whitegrid',color_codes=True)

#Preprocess
from keras.preprocessing.image import ImageDataGenerator

#dl libraraies
from keras import backend as K
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam,SGD,Adagrad,Adadelta,RMSprop
from keras.utils import to_categorical

# specifically for cnn
from keras.layers import Dropout, Flatten,Activation
from keras.layers import Conv2D, MaxPooling2D, BatchNormalization
plt.style.use('seaborn-dark-palette') 
 
# Ignore  the warnings
import warnings
warnings.filterwarnings('always')
warnings.filterwarnings('ignore')

# specifically for manipulating zipped images and getting numpy arrays of pixel values of images.
import cv2                  
import numpy as np  
from tqdm import tqdm
import os                   
from random import shuffle  
from PIL import Image

Loading data (Note : Please provide the path of your data in which data is stored)

In [33]:
# Loading data. Please keep the format as shown below ending with \\.
path_flower = "C:\\Users\\Janvi\\Documents\\Project\\New_Flowers\\"
path_fashion = "C:\\Users\\Janvi\\Documents\\Project\\Fashion\\"

Preparing data

There are total 4138 flower images we have used for image classification in which there are 5 subfolders of different flowers categories such as daisy, sunflower, tulip, dandelion, and rose. Now, in first step we have made directory for each folder of image and all of them are given labels with respect to their appropriate classes. For instance, all daisy images belongs to flower_daisy_dir, sunflower belongs to flower_sunflower_dir, etc and then we are saving all the directories in 'DIR' variable to use them in following code. Then we have labeled the flowers and resized the images because all the images might have different sizes so we have made all images to 150x150 size.

In [35]:
A=[]
B=[]
IMG_SIZE=150
FLOWER_DAISY_DIR= path_flower + 'daisy'
FLOWER_SUNFLOWER_DIR= path_flower + 'sunflower'
FLOWER_TULIP_DIR= path_flower + 'tulip'
FLOWER_DANDI_DIR= path_flower + 'dandelion'
FLOWER_ROSE_DIR= path_flower + 'rose'

DIR = path_flower

Instead of coding separately for each task, we designed two functions that would do all the task of reading the images, resizing it and labeling the array of images to their labels. Since our data has different folders containing individual categories of images, it became very easy for us to label the images during initial stages. Moreover, in below code we have printed the length of each subfolder of images. The length is being added after each count of subfolder for example, daisy images(749) + sunflower(698) = 1447 and rest for other images as well.So, in the end we can see that at the rose count it shows the total images of sub folders which is 4138 images.

In [36]:
# Label function to label the flowers
def assign_label(image,flower_type):
    return flower_type

#train data split
def make_train_data(flower_type,DIR):
    for image in tqdm(os.listdir(DIR)): #progress bar for better view
        label=assign_label(image,flower_type)
        path_flower = os.path.join(DIR,image)
        image = cv2.imread(path_flower,cv2.IMREAD_COLOR)
        image = cv2.resize(image, (IMG_SIZE,IMG_SIZE))
        
        A.append(np.array(image))
        B.append(str(label))

make_train_data('Daisy',FLOWER_DAISY_DIR)
print('Daisy Count: ',len(A))

make_train_data('Sunflower',FLOWER_SUNFLOWER_DIR)
print('Sunflower Count: ',len(A))

make_train_data('Tulip',FLOWER_TULIP_DIR)
print('Tulip Count: ',len(A))

make_train_data('Dandelion',FLOWER_DANDI_DIR)
print('Dandelion Count: ',len(A))

make_train_data('Rose',FLOWER_ROSE_DIR)
print('Rose Count: ',len(A))
100%|██████████| 749/749 [00:06<00:00, 118.25it/s]
  2%|▏         | 15/698 [00:00<00:04, 143.86it/s]Daisy Count:  749
100%|██████████| 698/698 [00:14<00:00, 49.42it/s]
  1%|▏         | 14/935 [00:00<00:06, 138.02it/s]Sunflower Count:  1447
100%|██████████| 935/935 [00:15<00:00, 62.33it/s]
  0%|          | 0/1028 [00:00<?, ?it/s]Tulip Count:  2382
100%|██████████| 1028/1028 [00:16<00:00, 61.74it/s]
  2%|▏         | 18/728 [00:00<00:04, 174.61it/s]Dandelion Count:  3410
100%|██████████| 728/728 [00:12<00:00, 60.00it/s]Rose Count:  4138

Visualizing different flower images

We performed some basic image resizing by changing the image to 150 x 150 size to remove the unwanted background. It is also a strict requirement for the application of CNN that all images are of the same size.

In [37]:
#Visualize Images
import random as rn
fig,ax=plt.subplots(5,3)
fig.set_size_inches(15,15)
for i in range(5):
    for j in range (3):
        l=rn.randint(0,len(B))
        ax[i,j].imshow(A[l])
        ax[i,j].set_title('Flower: '+B[l])
fig.suptitle('Loaded Images', color='Blue', fontsize=16)        
plt.tight_layout()
2020-12-16T23:23:00.043195 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

The next step of machine learning is encoding the labels in form of vectors. Since we have 5 categories of flowers, the whole array of flowers was divided into 5 different categories and divided by 255 (to range the value of pixels between 0 and 1) as the maximum pixel value of an 8-bit image is 255 (the brightest pixel).

In [38]:
from sklearn.preprocessing import LabelEncoder
from keras.utils import to_categorical
le=LabelEncoder()
q=le.fit_transform(B)
q=to_categorical(q,5)
A=np.array(A)
A=A/255
print('The data has been categorized')
The data has been categorized
In [39]:
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(A,q,test_size=0.25,random_state=42)
print('The data has been successfully split into test and train with 25% test data')
The data has been successfully split into test and train with 25% test data

The dataset was split into training and testing dataset. The training dataset contains 3103 images and testing contain 1035 images which is 75 percent and 25 percent of the dataset for respective purposes. The same number of images have also been used for the model validation and prediction.

In [40]:
# shape of the training and test set
#(x_train.shape, x_test.shape), (y_train.shape, y_test.shape)
# Understanding number of images, their shapes and size.
print('All images are of {}x{} size and have {} color channels'.format(x_train.shape[1],x_train.shape[2],x_train.shape[3]))
print('Number of images used for training the model as independent are: ',x_train.shape[0])
print('Number of images used for testing the model independent are: ',x_test.shape[0])
print('Number of images used for prediction in the model dependent are: ',y_train.shape[0])
print('Number of images used for testing accuracy between actual and predicted categories are: ',y_test.shape[0])
All images are of 150x150 size and have 3 color channels
Number of images used for training the model as independent are:  3103
Number of images used for testing the model independent are:  1035
Number of images used for prediction in the model dependent are:  3103
Number of images used for testing accuracy between actual and predicted categories are:  1035

Implementation of Sequential Model

Convolutional Neural Network (CNN) is one of the best machine learning models which are used for any techniques that can be applied for the models dealing in images. CNN takes inout as an image and extracts important feature from images and then this image is given as an input to max pooling layer which is our second step of our CNN model. In this next layer a filter of some size, for example, 5 x 5 x 3 which rotates over the whole image of 150 x 150 x 3 to extract various important features which is a result of dot product of filter and image and also it will pick maximum value based on the filter and then this value will be stored in feature map matrix. So, here we have used 4 layers of convolutional layer and 4 max pooling layer. After that we added on e droup out layer which will remove unwanted noise of images.The ninth layer is a flattening layer which converts the two-dimensional data into vector that can be fed into the fully connected networks. The activation layers we have used are relu and softmax layer in which reLu activation layer (f(x) = max(x,0)) assures that the output does not have any negative values as they can act as noise. However, the softmax function then assures that the output stays within the range of 0 and 1 using probability distribution. The dense layer is a fullt connected layer in which all neurons are connected to those on next layer.

In [41]:
# defining the model architecture
model = Sequential()
model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',activation ='relu', input_shape = (150,150,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
# model.add(Dropout(0.25))

model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same',activation ='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
#model.add(Dropout(0.25))

model.add(Conv2D(filters =96, kernel_size = (3,3),padding = 'Same',activation ='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
# model.add(Dropout(0.25))

model.add(Conv2D(filters = 96, kernel_size = (3,3),padding = 'Same',activation ='relu'))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(5, activation = "softmax"))

Now it comes to defining of batch size and epochs. So basically batch size will decide the number of training samples used in one iteration and epoch has had an opportunity to update the internal model parameters. Moreover, batch size should be equal to epoch or more than epoch size.Now, here we have used ReduceLROnPlateau in which the name itself explains that it reduces the learning rate of model when no improvement is seen after number of epochs. Below is some basic description of arguments of call back function(referred from https://keras.io/api/callbacks/reduce_lr_on_plateau/)

monitor: quantity to be monitored.

factor: factor by which the learning rate will be reduced. new_lr = lr * factor.

patience: number of epochs with no improvement after which learning rate will be reduced.

verbose: int. 0: quiet, 1: update messages.

mode: one of {'auto', 'min', 'max'}. In 'min' mode, the learning rate will be reduced when the quantity monitored has stopped decreasing; in 'max' mode it will be reduced when the quantity monitored has stopped increasing; in 'auto' mode, the direction is automatically inferred from the name of the monitored quantity.

min_delta: threshold for measuring the new optimum, to only focus on significant changes.

cooldown: number of epochs to wait before resuming normal operation after lr has been reduced.

min_lr: lower bound on the learning rate.

In [42]:
batch_size=16
epochs=15

from keras.callbacks import ReduceLROnPlateau
red_lr= ReduceLROnPlateau(monitor='val_accuracy',patience=3,verbose=1,factor=0.5)

Image data generator plays an important role in training datasets. It augments the data in various ways and also we can apply apply any random transformation to training images. Moreover, the augment term means over here is that variations of training set images that are mostly seen by a model. So after generating data generator it is supposed to be get fitted on training data and then it comes to compilation of model. Compile is the last step to build a model and it defines the loss and optimizer for a model as we need compiled model to train beacuse a model requires loss and optimizer function. Here, we have used Adam as an optimizer which is an exension version of Stochastic gradient decent(it ias an iterative method and it calculates the derivative form each training data and update it immideately). This optimizer than handle sparse gradient on noisy problems. Now the loss fucntion(categorical-crossentropy) will calculate the average probability betwwen the actual and predicted probablity for all classes in the model.

Moreover, in the model summary we can see that the first output shape of convolutional layer was (150,150,32) where 32 is the filter size and 150x150 is the metrix size. After the max pooling layer we can see that the matrix size decreased to 75x75 size matrix and the whole process is repeated until it reaches last layer of max pooling and after that drop out, flatten and activation layers plays their role in making image noise free and making the values of image non negative.

In [11]:
data_generator = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)
        zoom_range = 0.1, # Randomly zoom image 
        width_shift_range=0.2,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.2,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=False)  # randomly flip images


data_generator.fit(x_train)  

model.compile(optimizer=Adam(lr=0.001),loss='categorical_crossentropy',metrics=['accuracy'])

model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 150, 150, 32)      2432      
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 75, 75, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 75, 75, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 37, 37, 64)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 37, 37, 96)        55392     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 18, 18, 96)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 18, 18, 96)        83040     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 9, 9, 96)          0         
_________________________________________________________________
dropout (Dropout)            (None, 9, 9, 96)          0         
_________________________________________________________________
flatten (Flatten)            (None, 7776)              0         
_________________________________________________________________
dense (Dense)                (None, 512)               3981824   
_________________________________________________________________
activation (Activation)      (None, 512)               0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 5)                 2565      
=================================================================
Total params: 4,143,749
Trainable params: 4,143,749
Non-trainable params: 0
_________________________________________________________________

Training the model where validation is our test data. Loss and accuracy refers to training data performance and val_loss and val_acc refers to test data loss and accuracy. If validation accuracy goes higher than training accuracy that means model is performing well for test data and test data images are learning well after training it with 15 epochs. So we perfectly got our accuracy with 72% which is not at all bad. Many people need 50 epochs to improve their accuracy but we got 72% accuracy at just 15 epochs which saved our memory consumption as well as complexity of model.

In [12]:
History = model.fit(data_generator.flow(x_train,y_train, batch_size=batch_size),
                              epochs = epochs, validation_data = (x_test,y_test),
                              verbose = 1, steps_per_epoch=x_train.shape[0] // batch_size,callbacks=[red_lr])
Epoch 1/15
193/193 [==============================] - 113s 587ms/step - loss: 1.3498 - accuracy: 0.3965 - val_loss: 1.1558 - val_accuracy: 0.5130
Epoch 2/15
193/193 [==============================] - 102s 529ms/step - loss: 1.1217 - accuracy: 0.5364 - val_loss: 1.0441 - val_accuracy: 0.5836
Epoch 3/15
193/193 [==============================] - 93s 482ms/step - loss: 1.0270 - accuracy: 0.6019 - val_loss: 1.0314 - val_accuracy: 0.6338
Epoch 4/15
193/193 [==============================] - 88s 454ms/step - loss: 0.9889 - accuracy: 0.6122 - val_loss: 0.8953 - val_accuracy: 0.6686
Epoch 5/15
193/193 [==============================] - 86s 443ms/step - loss: 0.9100 - accuracy: 0.6602 - val_loss: 0.8532 - val_accuracy: 0.6686
Epoch 6/15
193/193 [==============================] - 86s 447ms/step - loss: 0.8754 - accuracy: 0.6605 - val_loss: 0.8143 - val_accuracy: 0.6870
Epoch 7/15
193/193 [==============================] - 86s 447ms/step - loss: 0.8467 - accuracy: 0.6793 - val_loss: 0.8267 - val_accuracy: 0.6995
Epoch 8/15
193/193 [==============================] - 100s 520ms/step - loss: 0.8148 - accuracy: 0.6874 - val_loss: 0.8112 - val_accuracy: 0.7005
Epoch 9/15
193/193 [==============================] - 106s 551ms/step - loss: 0.8051 - accuracy: 0.6923 - val_loss: 0.8000 - val_accuracy: 0.6947
Epoch 10/15
193/193 [==============================] - 110s 569ms/step - loss: 0.7831 - accuracy: 0.7059 - val_loss: 0.7278 - val_accuracy: 0.7343
Epoch 11/15
193/193 [==============================] - 88s 455ms/step - loss: 0.7752 - accuracy: 0.7110 - val_loss: 0.7355 - val_accuracy: 0.7372
Epoch 12/15
193/193 [==============================] - 88s 457ms/step - loss: 0.7413 - accuracy: 0.7250 - val_loss: 0.7141 - val_accuracy: 0.7391
Epoch 13/15
193/193 [==============================] - 90s 465ms/step - loss: 0.7322 - accuracy: 0.7266 - val_loss: 0.7084 - val_accuracy: 0.7362
Epoch 14/15
193/193 [==============================] - 90s 465ms/step - loss: 0.7012 - accuracy: 0.7454 - val_loss: 0.7197 - val_accuracy: 0.7304
Epoch 15/15
193/193 [==============================] - ETA: 0s - loss: 0.7098 - accuracy: 0.7340
Epoch 00015: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.
193/193 [==============================] - 89s 463ms/step - loss: 0.7098 - accuracy: 0.7340 - val_loss: 0.7096 - val_accuracy: 0.7285

Loss of model

Here the loss is decreasing from 1.3 to 0.7 as well we can see a gap between training and test loss which is also known as "generalization gap" which shows a good fit of a model. So our model perfectly fitted for flower images.

In [14]:
plt.plot(History.history['loss'], marker = "1")
plt.plot(History.history['val_loss'], marker = "x")
plt.title('Model loss over number of epochs', fontweight='bold', fontsize=14.0)
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.legend(['train', 'test'])
plt.show()
2020-12-11T21:20:24.185543 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

Accuracy of model

In this graph it shows the test accuracy is more tha training accuracy which shows that it is model is working perfectly fine for unseen images.

In [15]:
plt.plot(History.history['accuracy'], marker = "1")
plt.plot(History.history['val_accuracy'], marker = "x")
plt.title('Model accuracy over number of epochs', fontweight='bold', fontsize=14.0)
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['train', 'test'])
plt.show()
2020-12-11T21:20:27.442395 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

Saving model for future transfer learning process.(This model will be saved at your disk where this project file will be saved)

In [13]:
#Saving and loading model
# serialize weights to HDF5
model.save("model.h5")
print("Saved model to disk")
Saved model to disk

Here we are predicting the test data by using the trained model.Confusion matrix is plotted actual value vs predicted values. Moreover, to know which flower is correctly predicted and which is not we are plotting confusion matrix which is very important part to understand. So here we cn see that 161 daisy, 177 sunflower, 158 tulip, 149 dandelion, and 148 rose are correctly predicted out of 1035 testing data. With "np.argmax" we are defining the index of an array that results in largest value of predicted probablities. The predicted probablities are ordered in such a way that value 0 belongs to first class, 1 belongs to second class and so on.

In [17]:
# getting predictions on val set.
from sklearn.metrics import confusion_matrix
label=['Daisy','Sunflower','Tulip','Dandelion', 'Rose']
pred=model.predict(x_test)
pred_digits=np.argmax(pred,axis=1)
Y_true = np.argmax(y_test,axis = 1)
confusion_mtx = confusion_matrix(Y_true,pred_digits)
f,ax = plt.subplots(figsize = (8,8))
sns.heatmap(confusion_mtx,annot=True,linewidths = 0.01,cmap="YlGnBu",
            linecolor = "black",fmt = ".2f",ax=ax, xticklabels=label,yticklabels=label
            )
plt.xlabel("Predicted label",fontweight='bold', fontsize=13.0)
plt.ylabel("True Label",fontweight='bold', fontsize=13.0)
plt.title("Confusion matrix of test data",fontweight='bold', fontsize=16.0)
plt.show()
[2 1 1 ... 1 2 0]
2020-12-16T14:34:19.189120 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

Making indexes for properly and misclassified images.

In [19]:
# now storing some properly as well as misclassified indexes'.
i=0
prop_class=[]
mis_class=[]

for i in range(len(y_test)):
    if(np.argmax(y_test[i])==pred_digits[i]):
        prop_class.append(i)
    if(len(prop_class)==8):
        break

i=0
for i in range(len(y_test)):
    if(not np.argmax(y_test[i])==pred_digits[i]):
        mis_class.append(i)
    if(len(mis_class)==8):
        break

In above implementation of model we saw that flatten layer converts the input image to vector so to again convert vector data to images we have to use inverse Laplace transform to visulaize data in form of images. So here we have implemented Inverse Laplace Transform on predicted data.

In [20]:
count=0
fig,ax=plt.subplots(4,2)
fig.set_size_inches(15,15)
for i in range (4):
    for j in range (2):
        ax[i,j].imshow(x_test[prop_class[count]])
        ax[i,j].set_title("Predicted Flower :"+str(le.inverse_transform([pred_digits[prop_class[count]]]))+"\n"+"Actual Flower : "+str(le.inverse_transform([np.argmax(y_test[prop_class[count]])]))) 
        plt.tight_layout()
        count+=1
fig.suptitle('Correctly Classified Images', color='blue', fontsize=16)
Out[20]:
Text(0.5, 0.98, 'Correctly Classified Images')
2020-12-11T21:21:16.685510 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

The reason to get misclassified images are that sometimes because of angle of image model may misinterpret the images for instance, it mainly misinterpret the images between tulip and rose as they almost look like same when we see them at particular angle, same goes for dandelion and daisy. Moreover, we might can overcome from this error by training more dataset and increasing the epochs but as it also takes more memory consumption so we stick with 15 epochs which also gave us better accuracy.

In [21]:
#Misclassified images

count=0
fig,ax=plt.subplots(4,2)
fig.set_size_inches(15,15)
for i in range (4):
    for j in range (2):
        ax[i,j].imshow(x_test[mis_class[count]])
        ax[i,j].set_title("Predicted Flower :"+str(le.inverse_transform([pred_digits[mis_class[count]]]))+"\n"+"Actual Flower : "+str(le.inverse_transform([np.argmax(y_test[mis_class[count]])]))) 
        plt.tight_layout()
        count+=1
fig.suptitle('Incorrectly Classified Images', color='blue', fontsize=16)
Out[21]:
Text(0.5, 0.98, 'Incorrectly Classified Images')
2020-12-11T21:21:25.952511 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

Transfer Learning S-CNN MODEL FOR FASHION DATASET

Loading and labeling dataset.

In [43]:
#--------------------------- Fashion --------------------------------
# Directory
X=[]
Y=[]
img_size=150
Fashion_ho_DIR= path_fashion + 'hoodies'
Fashion_hofemale_DIR= path_fashion + 'hoodies-female'
Fashion_long_DIR= path_fashion + 'longsleeve'
Fashion_shirt_DIR=path_fashion + 'shirt'
Fashion_sweatshirt_DIR= path_fashion + 'sweatshirt'
Dir = path_fashion
In [44]:
# Label function to label the fashion
def assign_label(Image,fashion_type):
    return fashion_type

#train data split
def make_train_data(fashion_type,Dir):
    for Image in tqdm(os.listdir(Dir)): #progress bar for better view
        label=assign_label(Image,fashion_type)
        path_fashion = os.path.join(Dir,Image)
        Image = cv2.imread(path_fashion,cv2.IMREAD_COLOR)
        Image = cv2.resize(Image, (img_size,img_size))
        #img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        
        X.append(np.array(Image))
        Y.append(str(label))

make_train_data('hoodies',Fashion_ho_DIR)
print('hoodies: ',len(X))

make_train_data('hoodies-female',Fashion_hofemale_DIR)
print('hoodies-female: ',len(X))

make_train_data('longsleeve',Fashion_long_DIR)
print('longsleeve: ',len(X))

make_train_data('shirt',Fashion_shirt_DIR)
print('shirt: ',len(X))

make_train_data('sweatshirt',Fashion_sweatshirt_DIR)
print('sweatshirt: ',len(X))
100%|██████████| 2143/2143 [01:33<00:00, 23.02it/s]
  0%|          | 0/543 [00:00<?, ?it/s]hoodies:  2143
100%|██████████| 543/543 [00:24<00:00, 22.29it/s]
  1%|          | 4/643 [00:00<00:21, 30.23it/s]hoodies-female:  2686
100%|██████████| 643/643 [00:26<00:00, 23.88it/s]
  0%|          | 0/1015 [00:00<?, ?it/s]longsleeve:  3329
100%|██████████| 1015/1015 [00:53<00:00, 19.09it/s]
  0%|          | 0/510 [00:00<?, ?it/s]shirt:  4344
100%|██████████| 510/510 [00:31<00:00, 16.18it/s]sweatshirt:  4854

Here we repeating the same steps that we did earlier such as categorizing data and splitting training and testing data.

In [24]:
#Visualize Images
import random as rn
fig,ax=plt.subplots(5,3)
fig.set_size_inches(15,15)
for i in range(5):
    for j in range (3):
        l=rn.randint(0,len(Y))
        ax[i,j].imshow(X[l])
        ax[i,j].set_title('Fashion: '+Y[l])
fig.suptitle('Loaded Fashion Images', color='Blue', fontsize=16)           
plt.tight_layout()

from sklearn.preprocessing import LabelEncoder
from keras.utils import to_categorical
le=LabelEncoder()
p=le.fit_transform(Y)
p=to_categorical(p,5)
X=np.array(X)
X=X/255

from sklearn.model_selection import train_test_split
xtrain,xtest,ytrain,ytest=train_test_split(X,p,test_size=0.25,random_state=42)
# shape of the training and test set
(xtrain.shape, xtest.shape), (ytrain.shape, ytest.shape)
Out[24]:
(((3640, 150, 150, 3), (1214, 150, 150, 3)), ((3640, 5), (1214, 5)))
2020-12-11T21:24:49.895973 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

Loading the model which we have saved earlier for transfer learning. So here comes the part where we implement transfer learning method in which the pretrained model is used for second task of data. As we know that there are many pretrained models are available for better use but here we made our own custom model and used as a pretrained model which gave us a lot of knowledge for transfer learning.

In [25]:
#loading model
from keras.models import load_model
model_try = load_model('model.h5')

Training the fashion dataset by using our custom pretrained model.

In [33]:
History_fashion = model_try.fit(data_generator.flow(xtrain,ytrain, batch_size=batch_size),
                              epochs = epochs, validation_data = (xtest,ytest),
                              verbose = 1, steps_per_epoch=xtrain.shape[0] // batch_size,callbacks=[red_lr])
Epoch 1/15
227/227 [==============================] - 109s 478ms/step - loss: 1.1052 - accuracy: 0.5875 - val_loss: 0.9005 - val_accuracy: 0.6870
Epoch 2/15
227/227 [==============================] - 102s 451ms/step - loss: 0.9915 - accuracy: 0.6305 - val_loss: 0.7885 - val_accuracy: 0.7100
Epoch 3/15
227/227 [==============================] - 103s 454ms/step - loss: 0.9147 - accuracy: 0.6667 - val_loss: 0.7667 - val_accuracy: 0.7100
Epoch 4/15
227/227 [==============================] - 102s 450ms/step - loss: 0.8732 - accuracy: 0.6805 - val_loss: 0.7746 - val_accuracy: 0.7076
Epoch 5/15
227/227 [==============================] - ETA: 0s - loss: 0.8332 - accuracy: 0.6948
Epoch 00005: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.
227/227 [==============================] - 103s 452ms/step - loss: 0.8332 - accuracy: 0.6948 - val_loss: 0.7971 - val_accuracy: 0.6837
Epoch 6/15
227/227 [==============================] - 103s 453ms/step - loss: 0.8079 - accuracy: 0.7058 - val_loss: 0.6905 - val_accuracy: 0.7446
Epoch 7/15
227/227 [==============================] - 103s 455ms/step - loss: 0.7590 - accuracy: 0.7301 - val_loss: 0.6655 - val_accuracy: 0.7512
Epoch 8/15
227/227 [==============================] - 102s 450ms/step - loss: 0.7535 - accuracy: 0.7351 - val_loss: 0.6527 - val_accuracy: 0.7611
Epoch 9/15
227/227 [==============================] - 111s 489ms/step - loss: 0.7213 - accuracy: 0.7387 - val_loss: 0.6480 - val_accuracy: 0.7562
Epoch 10/15
227/227 [==============================] - 132s 580ms/step - loss: 0.7029 - accuracy: 0.7420 - val_loss: 0.6295 - val_accuracy: 0.7768
Epoch 11/15
227/227 [==============================] - 108s 477ms/step - loss: 0.6996 - accuracy: 0.7445 - val_loss: 0.6699 - val_accuracy: 0.7389
Epoch 12/15
227/227 [==============================] - 107s 473ms/step - loss: 0.6926 - accuracy: 0.7390 - val_loss: 0.6102 - val_accuracy: 0.7727
Epoch 13/15
227/227 [==============================] - 112s 491ms/step - loss: 0.6843 - accuracy: 0.7492 - val_loss: 0.5887 - val_accuracy: 0.7809
Epoch 14/15
227/227 [==============================] - 114s 504ms/step - loss: 0.6618 - accuracy: 0.7632 - val_loss: 0.5799 - val_accuracy: 0.7916
Epoch 15/15
227/227 [==============================] - 122s 537ms/step - loss: 0.6410 - accuracy: 0.7718 - val_loss: 0.5913 - val_accuracy: 0.7817

Now predicting the testing data of fashion dataset based on training dataset. Moreover, the confusion matrix describes that 470 hoodies, 73 Hoodies of female, 126 longsleeve, 238 shirt and 42 sweatshirt are perfectly predicted images out of 1214 test images.

In [38]:
# getting predictions on val set.
pred1=model_try.predict(xtest)
pred_digits1=np.argmax(pred1,axis=1)
from sklearn.metrics import confusion_matrix
label=['Hoodies','Hoodies-female','Longsleeve','Shirt', 'Sweatshirt']
Y_true1 = np.argmax(ytest,axis = 1)
confusion_mtx1 = confusion_matrix(Y_true1,pred_digits1)
f,ax = plt.subplots(figsize = (8,8))
sns.heatmap(confusion_mtx1,annot=True,linewidths = 0.01,cmap="YlGnBu",
            linecolor = "black",fmt = ".2f",ax=ax, xticklabels=label,yticklabels=label
            )
plt.xlabel("Predicted label",fontweight='bold', fontsize=13.0)
plt.ylabel("True Label",fontweight='bold', fontsize=13.0)
plt.title("Confusion matrix of test data(fashion)",fontweight='bold', fontsize=16.0)
plt.show()
2020-12-11T22:35:49.011463 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
In [35]:
# now storing some properly as well as misclassified indexes'.
i=0
prop_class1=[]
mis_class1=[]

for i in range(len(ytest)):
    if(np.argmax(ytest[i])==pred_digits1[i]):
        prop_class1.append(i)
    if(len(prop_class1)==8):
        break

i=0
for i in range(len(ytest)):
    if(not np.argmax(ytest[i])==pred_digits1[i]):
        mis_class1.append(i)
    if(len(mis_class1)==8):
        break

As we explianed above to visualize the images or to get the data in image form we have to do inverse laplace transform which again we are performing over here on test data of fashion. Below is the correctly classified imags of fashion.

In [36]:
count=0
fig,ax=plt.subplots(4,2)
fig.set_size_inches(15,15)
for i in range (4):
    for j in range (2):
        ax[i,j].imshow(xtest[prop_class1[count]])
        ax[i,j].set_title("Predicted Fashion :"+str(le.inverse_transform([pred_digits1[prop_class1[count]]]))+"\n"+"Actual Fashion : "+str(le.inverse_transform([np.argmax(ytest[prop_class1[count]])]))) 
        plt.tight_layout()
        count+=1
fig.suptitle('Correctly Classified Images', color='blue', fontsize=16)
Out[36]:
Text(0.5, 0.98, 'Correctly Classified Images')
2020-12-11T22:31:56.748242 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
In [37]:
#Misclassified images
count=0
fig,ax=plt.subplots(4,2)
fig.set_size_inches(15,15)
for i in range (4):
    for j in range (2):
        ax[i,j].imshow(xtest[mis_class1[count]])
        ax[i,j].set_title("Predicted Fashion :"+str(le.inverse_transform([pred_digits1[mis_class1[count]]]))+"\n"+"Actual Fashion : "+str(le.inverse_transform([np.argmax(ytest[mis_class1[count]])]))) 
        plt.tight_layout()
        count+=1
fig.suptitle('Incorrectly Classified Images', color='blue', fontsize=16)
Out[37]:
Text(0.5, 0.98, 'Incorrectly Classified Images')
2020-12-11T22:32:15.960637 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

IMPLEMENTING VGG AND INCEPTION MODEL ON FLOWERS DATASET

Making directories to visualize the general flower dataset and to check that data has been loaded properly or not.

In [18]:
# Making training and validation of dataset
train_dir = os.path.join(DIR, 'train')
validation_dir = os.path.join(DIR, 'validation')

# Directory with our training cat pictures
train_daisy_dir = os.path.join(train_dir, 'daisy')

# Directory with our training dog pictures
train_sunflower_dir = os.path.join(train_dir, 'sunflower')

# Directory with our training dog pictures
train_tulip_dir = os.path.join(train_dir, 'tulip')

# Directory with our validation cat pictures
validation_daisy_dir = os.path.join(validation_dir, 'daisy')

# Directory with our validation dog pictures
validation_sunflower_dir = os.path.join(validation_dir, 'sunflower')

# Directory with our validation dog pictures
validation_tulip_dir = os.path.join(validation_dir, 'tulip')
In [19]:
# Visualizing Images to make sure that Images have been loaded and working properly.
import matplotlib.image as mpimg
nrows = 4
ncols = 4

fig = plt.gcf()
fig.set_size_inches(ncols*4, nrows*4)
pic_index = 100
train_daisy_fnames = os.listdir( FLOWER_DAISY_DIR )
train_sunflower_fnames = os.listdir( FLOWER_SUNFLOWER_DIR )
train_tulip_fnames = os.listdir( FLOWER_TULIP_DIR )


next_daisy_pix = [os.path.join(FLOWER_DAISY_DIR, fname) 
                for fname in train_daisy_fnames[ pic_index-8:pic_index] 
               ]

next_sunflower_pix = [os.path.join(FLOWER_SUNFLOWER_DIR, fname) 
                for fname in train_sunflower_fnames[ pic_index-8:pic_index]
               ]

next_tulip_pix = [os.path.join(FLOWER_TULIP_DIR, fname) 
                for fname in train_tulip_fnames[ pic_index-8:pic_index]
               ]
for i, img_path in enumerate(next_tulip_pix+next_sunflower_pix+next_daisy_pix):
  # Set up subplot; subplot indices start at 1
  sp = plt.subplot(5, 5, i + 1)
  sp.axis('Off') # Don't show axes (or gridlines)

  img = mpimg.imread(img_path)
  plt.imshow(img)

plt.show()
2020-12-16T14:37:53.452272 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

Again here we are using data generator for both train and test data. We are using 2917 images for training data and 1246 for testing data.

In [20]:
data_generator1 = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)
        zoom_range = 0.1, # Randomly zoom image 
        width_shift_range=0.2,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.2,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=False,
        validation_split=0.3)  # Validation split images
img_width, img_height = 150, 150
train_gen = data_generator1.flow_from_directory(
        DIR, 
        target_size=(img_height, img_width), 
        batch_size=batch_size, 
        class_mode="categorical", 
        subset="training")
valid_gen = data_generator1.flow_from_directory(
        DIR, 
        target_size=(img_height, img_width), 
        batch_size=batch_size, 
        class_mode="categorical", 
        subset="validation")
Found 2917 images belonging to 6 classes.
Found 1246 images belonging to 6 classes.

Implementation of VGG and Inception model and just for the overview of pretrained model summary we have printed inception model summary.

In [21]:
from tensorflow.keras.applications.vgg16 import VGG16

#Shape of our images
#VCG Model 
base_model1 = VGG16(input_shape = (150, 150, 3), 
include_top = False, # Leave out the last fully connected layer
weights = 'imagenet')

#Inception model
from tensorflow.keras.applications.inception_v3 import InceptionV3
base_model = InceptionV3(input_shape = (150, 150, 3), include_top = False, weights = 'imagenet')
base_model.summary()
[0]              
__________________________________________________________________________________________________
conv2d_73 (Conv2D)              (None, 7, 7, 192)    147456      average_pooling2d_6[0][0]        
__________________________________________________________________________________________________
batch_normalization_60 (BatchNo (None, 7, 7, 192)    576         conv2d_64[0][0]                  
__________________________________________________________________________________________________
batch_normalization_63 (BatchNo (None, 7, 7, 192)    576         conv2d_67[0][0]                  
__________________________________________________________________________________________________
batch_normalization_68 (BatchNo (None, 7, 7, 192)    576         conv2d_72[0][0]                  
__________________________________________________________________________________________________
batch_normalization_69 (BatchNo (None, 7, 7, 192)    576         conv2d_73[0][0]                  
__________________________________________________________________________________________________
activation_61 (Activation)      (None, 7, 7, 192)    0           batch_normalization_60[0][0]     
__________________________________________________________________________________________________
activation_64 (Activation)      (None, 7, 7, 192)    0           batch_normalization_63[0][0]     
__________________________________________________________________________________________________
activation_69 (Activation)      (None, 7, 7, 192)    0           batch_normalization_68[0][0]     
__________________________________________________________________________________________________
activation_70 (Activation)      (None, 7, 7, 192)    0           batch_normalization_69[0][0]     
__________________________________________________________________________________________________
mixed7 (Concatenate)            (None, 7, 7, 768)    0           activation_61[0][0]              
                                                                 activation_64[0][0]              
                                                                 activation_69[0][0]              
                                                                 activation_70[0][0]              
__________________________________________________________________________________________________
conv2d_76 (Conv2D)              (None, 7, 7, 192)    147456      mixed7[0][0]                     
__________________________________________________________________________________________________
batch_normalization_72 (BatchNo (None, 7, 7, 192)    576         conv2d_76[0][0]                  
__________________________________________________________________________________________________
activation_73 (Activation)      (None, 7, 7, 192)    0           batch_normalization_72[0][0]     
__________________________________________________________________________________________________
conv2d_77 (Conv2D)              (None, 7, 7, 192)    258048      activation_73[0][0]              
__________________________________________________________________________________________________
batch_normalization_73 (BatchNo (None, 7, 7, 192)    576         conv2d_77[0][0]                  
__________________________________________________________________________________________________
activation_74 (Activation)      (None, 7, 7, 192)    0           batch_normalization_73[0][0]     
__________________________________________________________________________________________________
conv2d_74 (Conv2D)              (None, 7, 7, 192)    147456      mixed7[0][0]                     
__________________________________________________________________________________________________
conv2d_78 (Conv2D)              (None, 7, 7, 192)    258048      activation_74[0][0]              
__________________________________________________________________________________________________
batch_normalization_70 (BatchNo (None, 7, 7, 192)    576         conv2d_74[0][0]                  
__________________________________________________________________________________________________
batch_normalization_74 (BatchNo (None, 7, 7, 192)    576         conv2d_78[0][0]                  
__________________________________________________________________________________________________
activation_71 (Activation)      (None, 7, 7, 192)    0           batch_normalization_70[0][0]     
__________________________________________________________________________________________________
activation_75 (Activation)      (None, 7, 7, 192)    0           batch_normalization_74[0][0]     
__________________________________________________________________________________________________
conv2d_75 (Conv2D)              (None, 3, 3, 320)    552960      activation_71[0][0]              
__________________________________________________________________________________________________
conv2d_79 (Conv2D)              (None, 3, 3, 192)    331776      activation_75[0][0]              
__________________________________________________________________________________________________
batch_normalization_71 (BatchNo (None, 3, 3, 320)    960         conv2d_75[0][0]                  
__________________________________________________________________________________________________
batch_normalization_75 (BatchNo (None, 3, 3, 192)    576         conv2d_79[0][0]                  
__________________________________________________________________________________________________
activation_72 (Activation)      (None, 3, 3, 320)    0           batch_normalization_71[0][0]     
__________________________________________________________________________________________________
activation_76 (Activation)      (None, 3, 3, 192)    0           batch_normalization_75[0][0]     
__________________________________________________________________________________________________
max_pooling2d_7 (MaxPooling2D)  (None, 3, 3, 768)    0           mixed7[0][0]                     
__________________________________________________________________________________________________
mixed8 (Concatenate)            (None, 3, 3, 1280)   0           activation_72[0][0]              
                                                                 activation_76[0][0]              
                                                                 max_pooling2d_7[0][0]            
__________________________________________________________________________________________________
conv2d_84 (Conv2D)              (None, 3, 3, 448)    573440      mixed8[0][0]                     
__________________________________________________________________________________________________
batch_normalization_80 (BatchNo (None, 3, 3, 448)    1344        conv2d_84[0][0]                  
__________________________________________________________________________________________________
activation_81 (Activation)      (None, 3, 3, 448)    0           batch_normalization_80[0][0]     
__________________________________________________________________________________________________
conv2d_81 (Conv2D)              (None, 3, 3, 384)    491520      mixed8[0][0]                     
__________________________________________________________________________________________________
conv2d_85 (Conv2D)              (None, 3, 3, 384)    1548288     activation_81[0][0]              
__________________________________________________________________________________________________
batch_normalization_77 (BatchNo (None, 3, 3, 384)    1152        conv2d_81[0][0]                  
__________________________________________________________________________________________________
batch_normalization_81 (BatchNo (None, 3, 3, 384)    1152        conv2d_85[0][0]                  
__________________________________________________________________________________________________
activation_78 (Activation)      (None, 3, 3, 384)    0           batch_normalization_77[0][0]     
__________________________________________________________________________________________________
activation_82 (Activation)      (None, 3, 3, 384)    0           batch_normalization_81[0][0]     
__________________________________________________________________________________________________
conv2d_82 (Conv2D)              (None, 3, 3, 384)    442368      activation_78[0][0]              
__________________________________________________________________________________________________
conv2d_83 (Conv2D)              (None, 3, 3, 384)    442368      activation_78[0][0]              
__________________________________________________________________________________________________
conv2d_86 (Conv2D)              (None, 3, 3, 384)    442368      activation_82[0][0]              
__________________________________________________________________________________________________
conv2d_87 (Conv2D)              (None, 3, 3, 384)    442368      activation_82[0][0]              
__________________________________________________________________________________________________
average_pooling2d_7 (AveragePoo (None, 3, 3, 1280)   0           mixed8[0][0]                     
__________________________________________________________________________________________________
conv2d_80 (Conv2D)              (None, 3, 3, 320)    409600      mixed8[0][0]                     
__________________________________________________________________________________________________
batch_normalization_78 (BatchNo (None, 3, 3, 384)    1152        conv2d_82[0][0]                  
__________________________________________________________________________________________________
batch_normalization_79 (BatchNo (None, 3, 3, 384)    1152        conv2d_83[0][0]                  
__________________________________________________________________________________________________
batch_normalization_82 (BatchNo (None, 3, 3, 384)    1152        conv2d_86[0][0]                  
__________________________________________________________________________________________________
batch_normalization_83 (BatchNo (None, 3, 3, 384)    1152        conv2d_87[0][0]                  
__________________________________________________________________________________________________
conv2d_88 (Conv2D)              (None, 3, 3, 192)    245760      average_pooling2d_7[0][0]        
__________________________________________________________________________________________________
batch_normalization_76 (BatchNo (None, 3, 3, 320)    960         conv2d_80[0][0]                  
__________________________________________________________________________________________________
activation_79 (Activation)      (None, 3, 3, 384)    0           batch_normalization_78[0][0]     
__________________________________________________________________________________________________
activation_80 (Activation)      (None, 3, 3, 384)    0           batch_normalization_79[0][0]     
__________________________________________________________________________________________________
activation_83 (Activation)      (None, 3, 3, 384)    0           batch_normalization_82[0][0]     
__________________________________________________________________________________________________
activation_84 (Activation)      (None, 3, 3, 384)    0           batch_normalization_83[0][0]     
__________________________________________________________________________________________________
batch_normalization_84 (BatchNo (None, 3, 3, 192)    576         conv2d_88[0][0]                  
__________________________________________________________________________________________________
activation_77 (Activation)      (None, 3, 3, 320)    0           batch_normalization_76[0][0]     
__________________________________________________________________________________________________
mixed9_0 (Concatenate)          (None, 3, 3, 768)    0           activation_79[0][0]              
                                                                 activation_80[0][0]              
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 3, 3, 768)    0           activation_83[0][0]              
                                                                 activation_84[0][0]              
__________________________________________________________________________________________________
activation_85 (Activation)      (None, 3, 3, 192)    0           batch_normalization_84[0][0]     
__________________________________________________________________________________________________
mixed9 (Concatenate)            (None, 3, 3, 2048)   0           activation_77[0][0]              
                                                                 mixed9_0[0][0]                   
                                                                 concatenate[0][0]                
                                                                 activation_85[0][0]              
__________________________________________________________________________________________________
conv2d_93 (Conv2D)              (None, 3, 3, 448)    917504      mixed9[0][0]                     
__________________________________________________________________________________________________
batch_normalization_89 (BatchNo (None, 3, 3, 448)    1344        conv2d_93[0][0]                  
__________________________________________________________________________________________________
activation_90 (Activation)      (None, 3, 3, 448)    0           batch_normalization_89[0][0]     
__________________________________________________________________________________________________
conv2d_90 (Conv2D)              (None, 3, 3, 384)    786432      mixed9[0][0]                     
__________________________________________________________________________________________________
conv2d_94 (Conv2D)              (None, 3, 3, 384)    1548288     activation_90[0][0]              
__________________________________________________________________________________________________
batch_normalization_86 (BatchNo (None, 3, 3, 384)    1152        conv2d_90[0][0]                  
__________________________________________________________________________________________________
batch_normalization_90 (BatchNo (None, 3, 3, 384)    1152        conv2d_94[0][0]                  
__________________________________________________________________________________________________
activation_87 (Activation)      (None, 3, 3, 384)    0           batch_normalization_86[0][0]     
__________________________________________________________________________________________________
activation_91 (Activation)      (None, 3, 3, 384)    0           batch_normalization_90[0][0]     
__________________________________________________________________________________________________
conv2d_91 (Conv2D)              (None, 3, 3, 384)    442368      activation_87[0][0]              
__________________________________________________________________________________________________
conv2d_92 (Conv2D)              (None, 3, 3, 384)    442368      activation_87[0][0]              
__________________________________________________________________________________________________
conv2d_95 (Conv2D)              (None, 3, 3, 384)    442368      activation_91[0][0]              
__________________________________________________________________________________________________
conv2d_96 (Conv2D)              (None, 3, 3, 384)    442368      activation_91[0][0]              
__________________________________________________________________________________________________
average_pooling2d_8 (AveragePoo (None, 3, 3, 2048)   0           mixed9[0][0]                     
__________________________________________________________________________________________________
conv2d_89 (Conv2D)              (None, 3, 3, 320)    655360      mixed9[0][0]                     
__________________________________________________________________________________________________
batch_normalization_87 (BatchNo (None, 3, 3, 384)    1152        conv2d_91[0][0]                  
__________________________________________________________________________________________________
batch_normalization_88 (BatchNo (None, 3, 3, 384)    1152        conv2d_92[0][0]                  
__________________________________________________________________________________________________
batch_normalization_91 (BatchNo (None, 3, 3, 384)    1152        conv2d_95[0][0]                  
__________________________________________________________________________________________________
batch_normalization_92 (BatchNo (None, 3, 3, 384)    1152        conv2d_96[0][0]                  
__________________________________________________________________________________________________
conv2d_97 (Conv2D)              (None, 3, 3, 192)    393216      average_pooling2d_8[0][0]        
__________________________________________________________________________________________________
batch_normalization_85 (BatchNo (None, 3, 3, 320)    960         conv2d_89[0][0]                  
__________________________________________________________________________________________________
activation_88 (Activation)      (None, 3, 3, 384)    0           batch_normalization_87[0][0]     
__________________________________________________________________________________________________
activation_89 (Activation)      (None, 3, 3, 384)    0           batch_normalization_88[0][0]     
__________________________________________________________________________________________________
activation_92 (Activation)      (None, 3, 3, 384)    0           batch_normalization_91[0][0]     
__________________________________________________________________________________________________
activation_93 (Activation)      (None, 3, 3, 384)    0           batch_normalization_92[0][0]     
__________________________________________________________________________________________________
batch_normalization_93 (BatchNo (None, 3, 3, 192)    576         conv2d_97[0][0]                  
__________________________________________________________________________________________________
activation_86 (Activation)      (None, 3, 3, 320)    0           batch_normalization_85[0][0]     
__________________________________________________________________________________________________
mixed9_1 (Concatenate)          (None, 3, 3, 768)    0           activation_88[0][0]              
                                                                 activation_89[0][0]              
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 3, 3, 768)    0           activation_92[0][0]              
                                                                 activation_93[0][0]              
__________________________________________________________________________________________________
activation_94 (Activation)      (None, 3, 3, 192)    0           batch_normalization_93[0][0]     
__________________________________________________________________________________________________
mixed10 (Concatenate)           (None, 3, 3, 2048)   0           activation_86[0][0]              
                                                                 mixed9_1[0][0]                   
                                                                 concatenate_1[0][0]              
                                                                 activation_94[0][0]              
==================================================================================================
Total params: 21,802,784
Trainable params: 21,768,352
Non-trainable params: 34,432
__________________________________________________________________________________________________

After loading and defining both models we have to add flatten and dense layer to remove unwanted noise and range the pixels value between 0 to 1. Moreover, here we have used optimizer as an RMSprop as an optimizer as it gradient based optimization technique which is used in neural networks for training data. Gradient have tendency to vanish as data propogates to through the function. RMSprop deals with the issues which uses moving average of squared gradients to normalize the gradients. In simple way, RMSprop uses an adaptive learning rate instead of using steady or hyperparameter which means the learning rate changes over time.

In [22]:
from tensorflow.keras import layers
# Flatten the output layer to 1 dimension
x = layers.Flatten()(base_model1.output)
y= layers.Flatten()(base_model.output)
# Add a fully connected layer with 512 hidden units and ReLU activation
x = layers.Dense(512, activation='relu')(x)
y= layers.Dense(512, activation='relu')(y)
# Add a dropout rate of 0.5
x = layers.Dropout(0.5)(x)
y = layers.Dropout(0.5)(y)

# Add a final sigmoid layer for classification
x = layers.Dense(1, activation='sigmoid')(x)
y = layers.Dense(1, activation='sigmoid')(y)

model_1 = tf.keras.models.Model(base_model1.input, x)
model_2 = tf.keras.models.Model(base_model.input, y)

model_1.compile(optimizer = tf.keras.optimizers.RMSprop(lr=0.0001), loss = 'binary_crossentropy',metrics = ['acc'])
model_2.compile(optimizer = tf.keras.optimizers.RMSprop(lr=0.0001), loss = 'binary_crossentropy',metrics = ['acc'])

Implementation of VGG model on training data with 5 epochs.(Note: In both pretrained model we have kept epochs 5 because accuracy remains steady and also it takes lots of time to run one epoch because of plethora of cnn layers in both models)

In [23]:
#training VCG model and generating accuaracy and loss of models.
vgghist = model_1.fit(train_gen, validation_data = valid_gen, steps_per_epoch = 100, epochs = 5)
Epoch 1/5
100/100 [==============================] - 686s 7s/step - loss: 0.5974 - acc: 0.8124 - val_loss: 0.4520 - val_acc: 0.8333
Epoch 2/5
100/100 [==============================] - 653s 7s/step - loss: 0.4586 - acc: 0.8333 - val_loss: 0.4610 - val_acc: 0.8333
Epoch 3/5
100/100 [==============================] - 574s 6s/step - loss: 0.4551 - acc: 0.8333 - val_loss: 0.4507 - val_acc: 0.8333
Epoch 4/5
100/100 [==============================] - 664s 7s/step - loss: 0.4536 - acc: 0.8333 - val_loss: 0.4507 - val_acc: 0.8333
Epoch 5/5
100/100 [==============================] - 673s 7s/step - loss: 0.4524 - acc: 0.8333 - val_loss: 0.4526 - val_acc: 0.8333

Implementation of Inception model on training data with 5 epochs.

In [47]:
#training Inception model and generating accuaracy and loss of models.
inc_history = model_2.fit(train_gen, validation_data = valid_gen, steps_per_epoch = 100, epochs = 5)
Epoch 1/5
100/100 [==============================] - 270s 3s/step - loss: 0.5248 - acc: 0.8242 - val_loss: 0.4741 - val_acc: 0.8333
Epoch 2/5
100/100 [==============================] - 272s 3s/step - loss: 0.4616 - acc: 0.8333 - val_loss: 0.4593 - val_acc: 0.8333
Epoch 3/5
100/100 [==============================] - 276s 3s/step - loss: 0.4584 - acc: 0.8333 - val_loss: 0.4561 - val_acc: 0.8333
Epoch 4/5
100/100 [==============================] - 273s 3s/step - loss: 0.4568 - acc: 0.8333 - val_loss: 0.4581 - val_acc: 0.8333
Epoch 5/5
100/100 [==============================] - 275s 3s/step - loss: 0.4563 - acc: 0.8333 - val_loss: 0.4651 - val_acc: 0.8333

Visualizing both VGG and Inception model loss.

In [64]:
plt.plot(vgghist.history['loss'], marker = "1")
plt.plot(vgghist.history['val_loss'],marker = "x")
plt.title('Model Loss of VGG Model', fontweight='bold', fontsize=14.0)
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.legend(['train', 'test'])
plt.show()
2020-12-10T18:13:12.978118 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
In [71]:
plt.plot(inc_history.history['loss'],marker = "1" )
plt.plot(inc_history.history['val_loss'], marker = "x")
plt.title('Model Loss of Inception Model', fontweight='bold', fontsize=14.0)
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.ylim(0,1)
plt.xlim(0,10)
plt.legend(['train', 'test'])
plt.show()
2020-12-10T23:40:28.637271 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

In both above figure we can see that training loss is decreasing as model learns more and more from training data. Moreover, there is also generalization gap between both training and testing data which proves model as good fit for dataset.

Visualizing accuracy of VGG and Incepiton model.

In [24]:
plt.plot(vgghist.history['acc'], marker = "o")
plt.plot(vgghist.history['val_acc'], marker = "x")
plt.title('Model Accuracy of VGG Model', fontweight='bold', fontsize=14.0)
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['train', 'test'])
plt.show()
2020-12-16T18:40:35.644474 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/
In [67]:
plt.plot(inc_history.history['acc'], marker = "o")
plt.plot(inc_history.history['val_acc'], marker = "x")
plt.title('Model Accuracy of Inception Model', fontweight='bold', fontsize=14.0)
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['train', 'test'])
plt.show()
2020-12-10T18:13:15.374064 image/svg+xml Matplotlib v3.3.3, https://matplotlib.org/

From both above figure of accuracy we can conclude that training accuracy is increasing from 0.82 to 0.83 which does not show any major difference but still this models are high trained so accuracy remains steady at 0.83 as it has reached at its maximum training and loss point.Furthermore, it proves to be a good fit for flowers dataset.

--------------------------------END OF CODE----------------------------